package tt.dz.service.imp.charger;

import java.util.Date;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Service;

import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import redis.clients.jedis.Jedis;
import tt.dz.dao.base.OmsCommonDao;
import tt.dz.entity.base.JsonCommon;
import tt.dz.entity.base.JsonForList;
import tt.dz.entity.base.OmsCommonParam;
import tt.dz.entity.charger.OmsChargerBuildApply;
import tt.dz.entity.exception.OmsDaoException;
import tt.dz.entity.exception.OmsRedisException;
import tt.dz.service.charger.ChargerBuildApplyService;
import tt.dz.service.imp.base.BaseService;
import tt.dz.util.DateUtils;
import tt.dz.util.OmsConstant.MsgCodeEnum;
import tt.dz.util.RedisClient;
@Service @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
public class ChargerBuildApplyServiceImpl extends BaseService implements ChargerBuildApplyService{
	@Autowired
	@Qualifier("base")
	private OmsCommonDao<OmsChargerBuildApply> commonDaoImpl;
	@Autowired
	public ChargerBuildApplyServiceImpl(RedisTemplate<String, String> redisTemplate) {
		super();
		super.setRedisTemplate(redisTemplate);
	}

	@Override
	public synchronized JsonCommon<String> add(OmsChargerBuildApply obj) {
		
		try 
		{
			String sortNum = null;
			boolean redisNoError = true;
			try 
			{
				sortNum = this.getMaxIdFormRedis();
				obj.setSortNum(sortNum);
			}
			catch (OmsRedisException e) 
			{
				this.logError(e.getMessage(), e);
				redisNoError = false;
			}
			
			String id = this.genarateApplyId(obj);
			if (id == null)
			{
				return this.buildOtherJsonCommon(MsgCodeEnum.AS_RPC_PARAM_EMPTY_ERROR.getMsgCode(),
						"the request paramter userid is empty");
			}
			
			obj.setApply_id(id);
			obj.setValid_flag(1);
			Date now = new Date();
			obj.setCreate_time(now);
			obj.setUpdate_time(now);
			obj.setRead_flag(1);
			obj.setContact_flag(1);
			commonDaoImpl.add(obj);
			if(redisNoError)
			{
				this.writeMaxId2Redis(obj.getSortNum());
			}
			return this.buildSuccessJsonCommon("ok");
		} 
		catch (OmsDaoException e) 
		{
			return this.buildOtherJsonCommon(MsgCodeEnum.AS_RPC_SERVER_ERROR.getMsgCode(),
					MsgCodeEnum.AS_RPC_SERVER_ERROR.getMsgInfo());
		}
	}

	@Override
	public JsonCommon<?> update(OmsChargerBuildApply obj) {
		try 
		{
			commonDaoImpl.update(obj);
			return this.buildSuccessJsonCommon(obj);
		} 
		catch (OmsDaoException e) 
		{
			this.logError(e.getMessage(), e);
			return this.buildError400JsonCommon();
		}
	}

	@Override
	public JsonCommon<?> delete(String id) {
		if (StringUtils.isEmpty(id))
		{
			return this.buildOtherJsonCommon(MsgCodeEnum.ERROR400.getMsgCode(), "Error:the request id is empty");
		}
		try 
		{
			commonDaoImpl.deleteById(id, OmsChargerBuildApply.class);
			return this.buildSuccessJsonCommon("success");
		} catch (OmsDaoException e) {
			this.logError(e.getMessage(), e);
			return this.buildError400JsonCommon();
		}
	}

	@Override
	public JsonCommon<?> findById(String id) {
		if (StringUtils.isEmpty(id))
		{
			return this.buildOtherJsonCommon(MsgCodeEnum.ERROR400.getMsgCode(), "Error:the request id is empty");
		}
		try 
		{
			OmsChargerBuildApply apply = new OmsChargerBuildApply();
			apply.setApply_id(id);
			OmsChargerBuildApply op = commonDaoImpl.findRecordByPK(apply);
			return this.buildSuccessJsonCommon(op);
		} 
		catch (Exception e) 
		{
			this.logError(e.getMessage(), e);
			return this.buildError400JsonCommon();
		}
	}

	@Override
	public JsonForList<?> findPageObjs(OmsCommonParam param, OmsChargerBuildApply obj) {
		try 
		{
			List<OmsChargerBuildApply> lst = commonDaoImpl.pagingFind(param, obj);
			int total = 0;
			if (param.isQueryTotal())
			{
				total = commonDaoImpl.queryTotalByObject(obj);
			}
			return this.buildSuccessJsonForList(param, lst, total);
		} catch (Exception e) {
			this.logError(e.getMessage(), e);
			return this.buildError400JsonForList();
		}
	}
	
	private String genarateApplyId(OmsChargerBuildApply obj) throws OmsDaoException
	{
		String userId = obj.getUser_id();
		String sortNum = obj.getSortNum();
		if (userId != null)
		{
			if (sortNum == null)
			{
				sortNum = this.getMaxIdFromDb();
				obj.setSortNum(sortNum);
			}
			else
			{
				sortNum = this.genarateId(sortNum, 2);
			}
			
			if (userId.length() > 20)
			{
				userId = userId.substring(userId.length() -20, userId.length());
			}
			else if (userId.length() < 20 )
			{
				userId = this.stringFill(userId, 20, '0', true);
			}
			
			String date = DateUtils.formatCurrentDateShort();
			
			StringBuilder idSb = new StringBuilder();
			return idSb.append(userId).append(date).append(sortNum).toString();
		}
		return null;
		
	}
	
	private String getMaxIdFormRedis()throws OmsRedisException
	{
		try
		{
			String idKey = "idSequence:applyId";
			/*ValueOperations<String, String> ops = getRedisTemplate().opsForValue();
			return ops.get(idKey);*/
			return RedisClient.get(idKey);
		}
		catch(Exception e)
		{
			this.logError("redis query id error", e);
			throw new OmsRedisException(e);
		}
	}
	
	private void writeMaxId2Redis(String maxId)
	{
		try
		{
			String idKey = "idSequence:applyId";
			/*ValueOperations<String, String> ops = getRedisTemplate().opsForValue();
			ops.set(idKey, maxId);
			ops.increment(idKey, 1l);*/
			RedisClient.putString(idKey, maxId);
			Jedis jedis = RedisClient.getConnect();
			jedis.incrBy(idKey, 1l);
			jedis.close();
		}
		catch(Exception e)
		{
			this.logError("redis write id error", e);
			throw e;
		}
	}
	
	private String getMaxIdFromDb() throws OmsDaoException
	{
		String id = commonDaoImpl.findMaxPkIdBySingle(2, OmsChargerBuildApply.class);
		return this.genarateId(id, 2);
	}
	
	
	
	/**
	 * 字符串补齐
	 * @param source 源字符串
	 * @param fillLength 补齐长度
	 * @param fillChar 补齐的字符
	 * @param isLeftFill true为左补齐，false为右补齐
	 * @return
	 */
	private String stringFill(String source, int fillLength, char fillChar, boolean isLeftFill) {
	    if (source == null || source.length() >= fillLength) return source;
	     
	    StringBuilder result = new StringBuilder(fillLength);
	    int len = fillLength - source.length();
	    if (isLeftFill) {
	        for (; len > 0; len--) {
	            result.append(fillChar);
	        }
	        result.append(source);
	    } else {
	        result.append(source);
	        for (; len > 0; len--) {
	            result.append(fillChar);
	        }
	    }
	    return result.toString();
	}

	/* 
	 * 根据user_id及当前时间(天)计算下一apply_id
	 */
	@Override
	public String getApplyIdSeq(String user_id, String curDay) {
		String sql = "select max(apply_id) max_apply_id from oms_charger_build_apply where apply_id like '%"+user_id+curDay+"%'";
		List<Map<String,Object>> lsMap = this.commonDaoImpl.findDataBySql(sql, null);
		if(lsMap!=null&&lsMap.size()>0){
			String max_apply_id = (String) lsMap.get(0).get("max_apply_id");
			int next_apply_id = (Integer.parseInt(user_id+curDay+max_apply_id.substring(28)));
			return user_id+curDay+String.valueOf(next_apply_id);
		}
		else{
			return null;
		}
		
		
	}

}
